package com.itxh.factory;

import com.itxh.aware.Aware;
import com.itxh.aware.BeanFactoryAware;
import com.itxh.init.InitializingBean;
import com.itxh.model.BeanDefinition;
import com.itxh.model.PropertyValue;
import com.itxh.resolver.BeanDefinitionValueResolver;
import com.itxh.utils.ReflectUtils;

import java.util.List;

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{

    @Override
    protected Object doCreateBean(BeanDefinition bd) throws Exception{
        // 实例化（new对象）
        Object bean = createBeanInstance(bd);

        // 属性填充（依赖注入）
        populateBean(bd,bean);

        // 初始化
        initializeBean(bd,bean);

        return bean;
    }

    private void initializeBean(BeanDefinition bd, Object bean)  throws Exception{
        if (bean instanceof Aware){
            if (bean instanceof BeanFactoryAware){
                ((BeanFactoryAware)bean).setBeanFactory(this);
            }
        }

        if (bean instanceof InitializingBean){
            ((InitializingBean)bean).afterPropertiesSet();
        }

        String initMethod = bd.getInitMethod();
        if (initMethod == null || "".equals(initMethod)){
            return;
        }
        ReflectUtils.invokeMethod(bd.getClazzType(),bean,initMethod);
    }

    private void populateBean(BeanDefinition bd, Object bean) throws Exception{

        // 设置属性（可能会有多个属性，遍历处理）
        List<PropertyValue> propertyValues = bd.getPropertyValues();
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver((DefaultListableBeanFactory) this);
        for (PropertyValue propertyValue : propertyValues) {
            String name = propertyValue.getName();
            Object value = propertyValue.getValue();
//            Object valueToUse = handleValue(value);

            Object valueToUse = valueResolver.parseValue(value);

            ReflectUtils.setProperty(bd.getClazzType(),bean,name,valueToUse);
//            Field field = bd.getClazzType().getDeclaredField(name);
//            field.setAccessible(true);
//            field.set(bean,valueToUse);
        }
    }

    private Object createBeanInstance(BeanDefinition bd) throws Exception {

        return ReflectUtils.newInstance(bd.getClazzType());

//        Constructor<?> constructor = bd.getClazzType().getDeclaredConstructor();
//        Object bean = constructor.newInstance(); //默认调用无参的构造方法
//
//        return bean;
    }

    /*private List<TypeHandler> typeHandlers ;

    private Object handleValue(Object value) {
        if (value instanceof TypedStringValue){
            TypedStringValue typedStringValue = (TypedStringValue)value;
            String stringValue = typedStringValue.getValue();
            Class targetType = typedStringValue.getTargetType();

            if (typeHandlers != null){
                for (TypeHandler handler : typeHandlers) {
                    if (handler.isTargetHandler(targetType)){
                        return handler.handle(stringValue);
                    }
                }
            }

            if (targetType == String.class){
                return stringValue;
            }else if (targetType == Integer.class){
                return Integer.parseInt(stringValue);
            }// ...

        }else if (value instanceof RuntimeBeanReference){
            RuntimeBeanReference beanReference = (RuntimeBeanReference)value;
            String ref = beanReference.getRef();
            return getBean(ref);
        }
        return null;
    }*/
}
